﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ParallelArrays;
using FPA = Microsoft.ParallelArrays.FloatParallelArray;
using BPA = Microsoft.ParallelArrays.BoolParallelArray;
using IPA = Microsoft.ParallelArrays.IntParallelArray;
using PA = Microsoft.ParallelArrays.ParallelArrays;

namespace CoreCalc.SheetDefinedFunctions.Accellerator
{
    
    public class AccCond : AccExpr
    {
        private AccCompare comp;
        private AccExpr TrueLeaf;
        private AccExpr FalseLeaf;

        public enum Type
        {
            EQ, GT, GE, LT, LE, NQ
        }
        private Type type;

        public AccCond(Type opT,AccExpr arg1, AccExpr arg2, AccExpr TrueLeaf, AccExpr FalseLeaf)
        {
            comp = new AccCompare(opT,arg1,arg2);

            this.TrueLeaf = TrueLeaf;
            this.FalseLeaf = FalseLeaf;            
        }

        protected override FPA GenerateFPA(AccInputInfo info, int CallID)
        {
            return PA.Cond((BoolParallelArray)comp.GenerateBPA(info, CallID), TrueLeaf.GenerateFPAWithCache(info, CallID), FalseLeaf.GenerateFPAWithCache(info, CallID));
        }


        private class AccCompare
        {
            private AccExpr child1, child2;
            private Type type;

            public AccCompare(Type type, AccExpr v1, AccExpr v2)
            {
                this.type = type;
                this.child1 = v1;
                this.child2 = v2;
            }

            public BPA GenerateBPA(AccInputInfo info, int CallID)
            {
                FPA child1Fpa = child1.GenerateFPAWithCache(info, CallID);
                FPA child2Fpa = child2.GenerateFPAWithCache(info, CallID);
                switch(type) {
                    case Type.EQ:
                        return PA.CompareEqual(child1Fpa, child2Fpa);
                    case Type.GT:
                        return PA.CompareGreater(child1Fpa, child2Fpa);
                    case Type.GE:
                        return PA.CompareGreaterEqual(child1Fpa, child2Fpa);
                    case Type.LT:
                        return PA.CompareLess(child1Fpa, child2Fpa);
                    case Type.LE:
                        return PA.CompareLessEqual(child1Fpa, child2Fpa);
                    case Type.NQ:
                        return PA.CompareNotEqual(child1Fpa, child2Fpa);
                }
                throw new Exception("Unkwnown compare type");
            }
        }

    }
}
